﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.System;
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Windows8Accelerator.Core.Xaml.Helpers
{
    public class SettingsConfig
    {
        public SettingsPane SettingsPane { get; set; }
        public List<SettingsCommandHelper> Commands { get; set; }
    }

    public class SettingsCommandHelper
    {
        public Action Action { get; set; }
        public string Title { get; set; }
    }
    
    public static class SettingsContractHelper
    {
        private static Dictionary<Page, SettingsConfig> SettingsConfigs = new Dictionary<Page, SettingsConfig>();
        private static List<SettingsCommandHelper> AllPagesCommands = new List<SettingsCommandHelper>();

        private static void UnsubscribeForCommandsRequested(Page page)
        {
            if (SettingsConfigs.ContainsKey(page))
            {
                SettingsConfigs[page].SettingsPane.CommandsRequested -= CommandsRequested;
                SettingsConfigs.Remove(page);
            }
        }

        private static void page_Unloaded(object sender, RoutedEventArgs e)
        {
            UnsubscribeForCommandsRequested((Page)sender);
        }

        private static void CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
        {
            var settingsConfig = SettingsConfigs.Values.Where((c) => c.SettingsPane.Equals(sender)).FirstOrDefault();
            if (settingsConfig != null)
            {
                foreach (var command in settingsConfig.Commands)
                {
                    AddCommand(args, command);
                }
                foreach (var command in AllPagesCommands)
                {
                    AddCommand(args, command);
                }
            }
        }

        private static void AddCommand(SettingsPaneCommandsRequestedEventArgs args, SettingsCommandHelper command)
        {
            var commandId = string.Format("SettingsContractHelper:{0}", command.Title);
            if (!args.Request.ApplicationCommands.Any((ac) => commandId.Equals(ac.Id)))
            {
                var generalCommand = new SettingsCommand(
                    command,
                    command.Title,
                    new UICommandInvokedHandler(onSettingsCommand));
                args.Request.ApplicationCommands.Add(generalCommand);
            }
        }

        private static void onSettingsCommand(IUICommand command)
        {
            var commandHelper = command.Id as SettingsCommandHelper;
            commandHelper.Action();
        }

        public static void AddSettingsLink(string title, Page page, bool registerInAllPages, Uri uri)
        {
            AddSettingsCommand(title, page, registerInAllPages, () => {
                Launcher.LaunchUriAsync(uri);
            });
        }

        public static void AddSettingsCommand(string title, Page page, bool registerInAllPages, Action action)
        {
            InitializeSettingsPane(page);

            if (!registerInAllPages)
            {
                SettingsConfigs[page].Commands.Add(new SettingsCommandHelper()
                {
                    Title = title,
                    Action = action,
                });
            }
            else
            {
                AllPagesCommands.Add(new SettingsCommandHelper()
                {
                    Title = title,
                    Action = action,
                });

                if (AppHelper.Frame != null)
                {
                    AppHelper.Frame.Navigated += (sender, e) =>
                    {
                        var page1 = e.Content as Page;
                        if (page1 != null)
                        {
                            if (!SettingsConfigs.ContainsKey(page1))
                            {
                                SettingsConfigs[page1] = new SettingsConfig()
                                {
                                    SettingsPane = SettingsPane.GetForCurrentView(),
                                    Commands = new List<SettingsCommandHelper>(),
                                };
                                SettingsConfigs[page1].SettingsPane.CommandsRequested += CommandsRequested;
                                page1.Unloaded += page_Unloaded;
                            }
                        }
                    };
                }
            }
        }

        public static void RemoveSettingsCommand(string title, Page page)
        {
            InitializeSettingsPane(page);

            var command = SettingsConfigs[page].Commands.FirstOrDefault((c) => c.Title.Equals(title));
            if (command != null)
                SettingsConfigs[page].Commands.Remove(command);

            command = AllPagesCommands.FirstOrDefault((c) => c.Title.Equals(title));
            if (command != null)
                AllPagesCommands.Remove(command);
        }

        public static void InitializeSettingsPane(Page page)
        {
            if (page != null && !SettingsConfigs.ContainsKey(page))
            {
                SettingsConfigs[page] = new SettingsConfig()
                {
                    SettingsPane = SettingsPane.GetForCurrentView(),
                    Commands = new List<SettingsCommandHelper>(),
                };
                SettingsConfigs[page].SettingsPane.CommandsRequested += CommandsRequested;
                page.Unloaded += page_Unloaded;
            }
        }

    }
}
